(define (domain rovers)
  (:requirements :strips :equality)
  ; (:constants)
  (:predicates
    (Rover ?v)
    (Objective ?o)
    (Mode ?m)
    (Rock ?r)
    (Soil ?s)
    (Store ?s)
    (Lander ?l)
    (Type ?b ?t)

    (Conf ?v ?q)
    (Ray ?y)
    (Motion ?v ?q1 ?t ?q2)
    (ImageVisible ?v ?q ?y ?o)
    (ComVisible ?v ?q ?y ?l)
    (Above ?v ?q ?r)
    (CFreeRayConf ?y ?v ?q)

    (AtConf ?v ?q)
    (OnBoard ?c ?v)
    (Supports ?c ?m)
    (Calibrated ?c ?v)
    (HaveImage ?v ?o ?m)
    (ReceivedImage ?o ?m)
    (ReceivedAnalysis ?r)
    (Analyzed ?v ?r)
    (Free ?v ?s)
    (Full ?v ?s)

    (Blocked ?y)
  )
  ; (:functions)

  (:action move
    :parameters (?v ?q1 ?t ?q2)
    :precondition (and (Motion ?v ?q1 ?t ?q2)
                       (AtConf ?v ?q1))
    :effect (and (AtConf ?v ?q2)
                 (not (AtConf ?v ?q1)))
  )
  (:action take_image
    :parameters (?v ?q ?y ?o ?c ?m)
    :precondition (and (ImageVisible ?v ?q ?y ?o) (OnBoard ?c ?v) (Supports ?c ?m)
                       (AtConf ?v ?q) (Calibrated ?c ?v)
                       (not (Blocked ?y))
                  )
    :effect (and (HaveImage ?v ?o ?m)
                 (not (Calibrated ?c ?v)))
  )
  (:action calibrate
    :parameters (?v ?q ?y ?o ?c)
    :precondition (and (ImageVisible ?v ?q ?y ?o) (OnBoard ?c ?v)
                       (AtConf ?v ?q)
                       (not (Blocked ?y))
                  )
    :effect (Calibrated ?c ?v)
  )
  (:action send_image
    :parameters (?v ?q ?y ?l ?o ?m)
    :precondition (and (ComVisible ?v ?q ?y ?l) (Objective ?o) (Mode ?m)
                       (HaveImage ?v ?o ?m) (AtConf ?v ?q)
                       (not (Blocked ?y))
                  )
    :effect (ReceivedImage ?o ?m)
  )

  (:action sample_rock
    :parameters (?v ?q ?r ?s)
    :precondition (and (Above ?v ?q ?r) (Store ?s)
                       (AtConf ?v ?q) (Free ?v ?s))
    :effect (and (Full ?v ?s) (Analyzed ?v ?r)
                 (not (Free ?v ?s)))
  )
  (:action send_analysis
    :parameters (?v ?q ?y ?l ?r)
    :precondition (and (ComVisible ?v ?q ?y ?l) (Rock ?r)
                       (Analyzed ?v ?r) (AtConf ?v ?q)
                       (not (Blocked ?y))
                  )
    :effect (ReceivedAnalysis ?r)
  )
  (:action drop_rock
    :parameters (?v ?s)
    :precondition (and (Rover ?v) (Store ?s)
                       (Full ?v ?s))
    :effect (and (Free ?v ?s)
                 (not (Full ?v ?s)))
  )

  ;(:action recharge # TODO: sample states accessible by sun
  ;  :parameters (?v ?q)
  ;  :precondition (and (InSun ?q)
  ;                     (AtConf ?v ?q)
  ;                )
  ;  :effect (Charged ?v)
  ;)

  (:derived (Blocked ?y)
    (exists (?v ?q) (and (Ray ?y) (Conf ?v ?q)
                         (not (CFreeRayConf ?y ?v ?q))
                         (AtConf ?v ?q)))
  )

)